package com.company.jrlz.service;

import com.company.jrlz.service.opcua.config.OpcUaClientTemplate;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(PlcRWService.NAME)
public class PlcRWServiceBean implements PlcRWService {
    public static final Logger logger = LoggerFactory.getLogger(PlcRWServiceBean.class);

    @Lazy
    @Inject
    private OpcUaClientTemplate opcUaClientTemplate;

    @Override
    public boolean writeOpcuaFloat(String address, String floatValue) {
        float a = Float.parseFloat(floatValue);
        return opcUaClientTemplate.writeNodeValue(address,new Variant(a));
    }

    @Override
    public boolean writeOpcuaInt32(String address, String intValue) {
        Integer a = Integer.parseInt(intValue);
        return opcUaClientTemplate.writeNodeValue(address,new Variant(a));
    }

    @Override
    public boolean writeOpcuaBool(String address, String boolValue) {
        Boolean a = Boolean.parseBoolean(boolValue);
        return opcUaClientTemplate.writeNodeValue(address,new Variant(a));
    }

    @Override
    public boolean writeOpcuaStr(String address, String strValue) {
        return opcUaClientTemplate.writeNodeValue(address,new Variant(strValue));
    }
    @Override
    public boolean writeOpcuaShort(String address, String shortValue) {
        Short b = Short.parseShort(shortValue);
        return opcUaClientTemplate.writeNodeValue(address,new Variant(b));
    }
    @Override
    public boolean writeOpcuaList(Map<String, Object> writeMap, List<String> types) {
        System.out.println("lcy----------writeOpcuaList----writeMap:"+writeMap);
        List<String> nodeIds = new ArrayList<>();
        List<Variant> values = new ArrayList<>();
        nodeIds = new ArrayList<> (writeMap.keySet());
        int i =0;
        for (Object obj:writeMap.values()) {
            //values.add(new Variant(obj));
            values = objToVariant(values,obj,types,i);
            i++;
        }
        System.out.println("lcy---------values:"+values);

        boolean result = opcUaClientTemplate.writeNodeValueList(nodeIds, values);
        //result = true;
        return result;
    }

    private List<Variant> objToVariant(List<Variant> values,Object obj,List<String> types,int i){
        if(types.get(i).equals("Integer")){
            values.add(new Variant((Integer.parseInt(obj.toString()))));
        }else if(types.get(i).equals("Boolean")){
            values.add(new Variant((Boolean.parseBoolean(obj.toString()))));
        }else if(types.get(i).equals("Float")){
            values.add(new Variant((Float.parseFloat(obj.toString()))));
        }else if(types.get(i).equals("Double")){
            values.add(new Variant((Double.parseDouble(obj.toString()))));
        }else if(types.get(i).equals("Short")){
            values.add(new Variant((Short.parseShort(obj.toString()))));
        }else if(types.get(i).equals("String")){
            obj = obj == null?"":obj;
            values.add(new Variant((obj.toString())));
        }  else {
            values.add(new Variant((obj.toString())));
        }
        return values;
    }

    @Override
    public Float readFloat(String address) {
        float a = 1;
        try {
            a = Float.parseFloat(opcUaClientTemplate.readNodeVariant(address).getValue().getValue().toString());
        } catch (Exception e) {
            //System.out.println("lcy---------readFloat:异常");
            e.printStackTrace();
        }
        //System.out.println("lcy---------readFloat:"+a);
        return a;
    }

    @Override
    public Double readDouble(String address) {
        double a = 0;
        try {
            if(opcUaClientTemplate.readNodeVariant(address).getValue().getValue()!=null){
                a = Double.parseDouble(opcUaClientTemplate.readNodeVariant(address).getValue().getValue().toString());
            }
        } catch (Exception e) {
            //System.out.println("lcy---------readDouble:异常");
            e.printStackTrace();
        }
        //System.out.println("lcy---------readDouble:"+a);
        return a;
    }

    @Override
    public Integer readInt32(String address) {
        Integer a = 0;
        try {
            if(opcUaClientTemplate.readNodeVariant(address).getValue().getValue()!=null){
                a = Integer.valueOf(opcUaClientTemplate.readNodeVariant(address).getValue().getValue().toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        //System.out.println("lcy---------read----readInt32----"+address+":"+a);
        return a;
    }

    @Override
    public Boolean readBool(String address) {
        Boolean plcRequestOrder = false;
        try{
            if(opcUaClientTemplate.readNodeVariant(address).getValue().getValue()!=null){
                plcRequestOrder = Boolean.parseBoolean(opcUaClientTemplate.readNodeVariant(address).getValue().getValue().toString());
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return plcRequestOrder;
    }

    @Override
    public String readStr(String address) {
        String plcStr = "";
        try{
            if(opcUaClientTemplate.readNodeVariant(address).getValue().getValue()!=null){
                plcStr = opcUaClientTemplate.readNodeVariant(address).getValue().getValue().toString();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return plcStr;
    }

    @Override
    public Map<String, String> readListNodes(List<String> addressList) {
        System.out.println("lcy---------readListNodes:"+addressList);
        try {
            List<NodeId> nodeIds = new ArrayList<>();
            for (String address : addressList) {
                nodeIds.add(new NodeId(5,address));
            }
            List<DataValue> dataValueList = opcUaClientTemplate.readNodeListVariant(nodeIds);
            Map<String,String> values = new HashMap<>();

            for(int i=0;i<dataValueList.size();i++){
                String value = dataValueList.get(i).getValue().toString();
                System.out.println("lcy-----------readListNodes----"+addressList.get(i)+":"+value);
                values.put(addressList.get(i),value);
            }
            return values;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}